﻿Imports System.ComponentModel
Imports System.Drawing.Drawing2D
Imports FountainHead.ViewModel.Controls
Imports Fountainhead.Controls
Imports FountainHead.ViewModel
Imports FountainHead.ViewModel.Properties

Public Class StartScreen
    Implements INotifyPropertyChanged
    Private ctrlCollection() As BaseControlViewModel
    Private controlCount As Integer = 0
    Private _left As Integer = 10

    Private tempWireStart, tempWireEnd As Point
    Private tempWireTerminal As Terminal
    Private currentWire As Wire
    Private _Pen As Pen
    Private wireStartControlName As String
    Public Sub New()

        ' This call is required by the designer.
        InitializeComponent()

        ' Add any initialization after the InitializeComponent() call.
        drawWireValue = False
    End Sub

#Region "Properties"
    Private designModeValue As Boolean = True
    Public Property IsDesignMode As Boolean
        Get
            Return designModeValue
        End Get
        Set(ByVal value As Boolean)
            designModeValue = value
            RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs("DesignMode"))
        End Set
    End Property

    Private drawWireValue As Boolean
    Private Property drawWire As Boolean
        Get
            Return drawWireValue
        End Get
        Set(ByVal value As Boolean)
            If value = True Then
                Cursor = Cursors.Cross
            Else
                Cursor = Cursors.Arrow
            End If
            drawWireValue = value
        End Set
    End Property

#End Region



#Region "Base Control Events"
    Private Overloads Sub CreateControl(ByVal sender As Type)
        Dim myControl As BaseControl
        ReDim Preserve ctrlCollection(controlCount)
        'Adding control to the Array

        Select Case sender
            Case GetType(LabelControl)
                ctrlCollection(controlCount) = New LabelControlViewModel
                myControl = New LabelControl(ctrlCollection(controlCount))
            Case GetType(Adder)
                ctrlCollection(controlCount) = New AdderViewModel()
                myControl = New Adder(ctrlCollection(controlCount))
            Case Else
                ctrlCollection(controlCount) = New BaseControlViewModel
                myControl = New BaseControl(ctrlCollection(controlCount))

        End Select
        myControl.Left = _left
        myControl.Top = 200
        _left += 10
        controlCount += 1
        AddHandler myControl.Click, AddressOf ctrl_Click
        AddHandler myControl.MouseDown, AddressOf ctrl_MouseDown
        AddHandler myControl.MouseUp, AddressOf ctrl_MouseUp
        AddHandler myControl.MouseMove, AddressOf ctrl_MouseMove
        AddHandler myControl.PropertyChanged, AddressOf PropertyChangedHandler
        AddHandler myControl.LocationChanged, Sub() Invalidate()

        Me.Controls.Add(myControl)

        myControl.BringToFront()
    End Sub

    Private Sub ctrl_Click(ByVal sender As Object, ByVal e As MouseEventArgs)
        Dim vm = sender.ViewModel
        Select Case sender.GetType()
            Case GetType(LabelControl)
                LabelControlProperties.LabelProperty.ViewModel = vm
                gridProperty.SelectedObject = LabelControlProperties.LabelProperty
            Case GetType(Adder)
                AdderProperties.AdderProperty.ViewModel = vm
                gridProperty.SelectedObject = AdderProperties.AdderProperty

        End Select
        gridProperty.Refresh()
    End Sub

    Private Sub ctrl_MouseMove(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs)
        'OnMouseMove(e)

        If e.Button = MouseButtons.Left And drawWire Then
            Dim ctrl = Me.GetChildAtPoint(PointToClient(Cursor.Position))
            If ctrl IsNot Nothing AndAlso ctrl.CompanyName = "FountainHead.Controls" Then
                tempWireTerminal = CType(ctrl, BaseControl).NearestTerminal(PointToClient(Cursor.Position))
                tempWireEnd = tempWireTerminal.Point
            Else
                tempWireEnd = PointToClient(Cursor.Position)
            End If
            Invalidate()
        End If

    End Sub

    Private Sub ctrl_MouseDown(ByVal sender As Object, ByVal e As MouseEventArgs)
        If drawWire = True AndAlso e.Button = Windows.Forms.MouseButtons.Left Then
            Dim ctrl = Me.GetChildAtPoint(PointToClient(Cursor.Position))
            currentWire = New Wire(ctrl)
            currentWire.StartWire(ctrl, PointToClient(Cursor.Position))
            tempWireStart = currentWire.TerminalOne.Point
        End If
    End Sub

    Private Sub ctrl_MouseUp(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs)
        Try
            If e.Button = MouseButtons.Left And drawWire Then
                Dim ctrl = Me.GetChildAtPoint(PointToClient(Cursor.Position))
                If ctrl IsNot Nothing AndAlso ctrl.CompanyName = "FountainHead.Controls" AndAlso ctrl.Name <> wireStartControlName Then
                    currentWire.FinishedWire(ctrl, tempWireTerminal)
                    WireCollection.Add(currentWire)
                    currentWire = Nothing
                    drawWire = False
                End If
            End If
        Catch ex As Exception
            MessageBox.Show(ex.Message)
        Finally
            drawWire = False
            Invalidate()
        End Try
    End Sub

#End Region

#Region "Form Events"

    Protected Overrides Sub OnPaint(ByVal e As System.Windows.Forms.PaintEventArgs)
        Dim g As Graphics
        g = e.Graphics

        g.SmoothingMode = SmoothingMode.AntiAlias
        If WireCollection.Count > 0 Then
            For Each wire In WireCollection
                g.DrawPath(_Pen, wire.Path)
            Next
        End If
        If drawWire Then
            Dim path = New GraphicsPath()
            path.AddLine(tempWireStart, tempWireEnd)
            g.DrawPath(_Pen, path)
            'g.DrawPath(_Pen, tempWire.Path)
        End If
        MyBase.OnPaint(e)
    End Sub

    Private Sub StartScreen_Load(ByVal sender As Object, ByVal e As EventArgs) Handles MyBase.Load
        AddHandler PropertyChanged, AddressOf PropertyChangedHandler
        IsDesignMode = True

        'Enable Double-Buffering to stop the flicker on ReDraw
        SetStyle(ControlStyles.UserPaint, True)
        SetStyle(ControlStyles.AllPaintingInWmPaint, True)
        SetStyle(ControlStyles.DoubleBuffer, True)
        _Pen = New Pen(Color.Red, 3)
        WireCollection = New List(Of Wire)
    End Sub

    Private Sub StartScreen_MouseDown(ByVal sender As System.Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles MyBase.MouseDown
        If drawWire = True AndAlso e.Button = Windows.Forms.MouseButtons.Left Then
            'Me.Invalidate()
        End If
    End Sub

    Private Sub StartScreen_MouseClick(ByVal sender As System.Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles MyBase.MouseClick
        drawWire = False
        Cursor = Cursors.Arrow
        Dim _wire As Wire = Nothing
        If e.Button = Windows.Forms.MouseButtons.Right Then
            For Each wire In WireCollection
                If wire.Path.IsOutlineVisible(PointToClient(Cursor.Position), _Pen) Then
                    _wire = wire
                End If
            Next
            If _wire IsNot Nothing Then WireCollection.Remove(_wire)
            Invalidate()
        End If
    End Sub

    Private Sub Label1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Label1.Click
        CreateControl(GetType(LabelControl))
    End Sub

    Private Sub Label3_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Label3.Click
        Cursor = Cursors.Cross
        drawWire = True
    End Sub

    Private Sub Label5_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Label5.Click
        CreateControl(GetType(Adder))
    End Sub
#End Region

    Private Event PropertyChanged(ByVal sender As Object, ByVal e As PropertyChangedEventArgs) Implements INotifyPropertyChanged.PropertyChanged

    Private Sub PropertyChangedHandler(ByVal sender As Object, ByVal e As PropertyChangedEventArgs)
        Select Case e.PropertyName
            Case "RefreshPropertyGrid"
                ctrl_Click(sender, Nothing)

        End Select
    End Sub



#Region "Methods"
    Private WireCollection As List(Of Wire)



#End Region


    Private Sub gridProperty_PropertyValueChanged(s As Object, e As PropertyValueChangedEventArgs) Handles gridProperty.PropertyValueChanged
        gridProperty.Refresh()
    End Sub
End Class
